<!DOCTYPE html>
<html>
<head hexo-theme='https://volantis.js.org/#3.0-beta2'>
  <meta charset="utf-8">
  <!-- SEO相关 -->
  
    
  
  <!-- 渲染优化 -->
  <meta name="renderer" content="webkit">
  <meta name="force-rendering" content="webkit">
  <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
  <meta name="HandheldFriendly" content="True" >
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

  <!-- 页面元数据 -->
  
  <title>前端知识面试汇总 - 河豚吞吞</title>
  
    <meta name="keywords" content="其他">
  

  
    <meta name="description" content="Sometimes you have to reach into someone else’s world to find out what’s missing in your own.">
  

  <!-- feed -->
  

  <!-- import meta -->
  
    
      <meta name="msapplication-TileColor" content="#ffffff">
    
      <meta name="msapplication-config" content="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/browserconfig.xml">
    
      <meta name="theme-color" content="#ffffff">
    
  

  <!-- link -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.13/css/all.min.css">
  
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css">


  
    
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-waves@0.7.6/dist/waves.min.css">

  

  

  
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer@1.10/dist/APlayer.min.css">
  

  

  <!-- import link -->
  
  
  <link rel="apple-touch-icon" sizes="180x180" href="/lemonElf/img/icon/icon001.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/lemonElf/img/icon/icon001.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/lemonElf/img/icon/icon001.png">
  <link rel="manifest" href="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/favicon/site.webmanifest">
  <link rel="mask-icon" href="/lemonElf/img/icon/icon001.png" color="#5bbad5">
  <link rel="shortcut icon" href="/lemonElf/img/icon/icon001.png">
  

  
  
    
<link rel="stylesheet" href="/lemonelf/css/style.css">

  

  
  
</head>

<body>
  
  
  
  <div class="cover-wrapper">
    <cover class='cover post' style="display: none;">
      <div class='cover-body'>
  <div class='a'>
    
    
      <p class="title">MissGlobeFish</p>
    
    
      <p class="subtitle">When the world turns its back on you, you turn your back on the world! And only embrace whats next!</p>
    
  </div>
  <div class='b'>
    <div class='menu navigation dock'>
      <div class='list-h'>
        
          
            <a href="/lemonelf/"
              
              
              id="lemonelf">
              <img src='https://i.loli.net/2020/07/24/skczZ1VdMGRbTLi.png'><p>主页</p>
            </a>
          
            <a href="/lemonelf/archives/"
              
              
              id="lemonelfarchives">
              <img src='https://i.loli.net/2020/07/24/GaeXvVAdtJkCYT3.png'><p>归档</p>
            </a>
          
            <a href="/lemonelf/categories/"
              
              
              id="lemonelfcategories">
              <img src='https://i.loli.net/2020/07/24/9kHJZNA8m4RBxhp.png'><p>分类</p>
            </a>
          
            <a href="/lemonelf/friends/"
              
              
              id="lemonelffriends">
              <img src='https://i.loli.net/2020/07/24/cxRslyWzk2OTP9r.png'><p>友链</p>
            </a>
          
        
      </div>
    </div>
  </div>
</div>

      <div class="scroll-down" style="display: none;"><i class="fa fa-chevron-down scroll-down-effects"></i></div>
    </cover>
    <header class="l_header shadow blur">
  <div class='container'>
  <div class='wrapper'>
    <div class='nav-sub'>
      <p class="title"></p>
      <ul class='switcher nav-list-h' id="pjax-header-nav-list">
        <li><a class="s-comment fas fa-comments fa-fw" target="_self" href='javascript:void(0)'></a></li>
        
          <li><a class="s-toc fas fa-list fa-fw" target="_self" href='javascript:void(0)'></a></li>
        
      </ul>
    </div>
		<div class="nav-main">
      
        
        <a class="title flat-box" target="_self" href='/lemonelf/'>
          
          
          
            MissGlobeFish
          
        </a>
      

			<div class='menu navigation'>
				<ul class='nav-list-h'>
          
          
          
            
            
              <li>
                <a class="menuitem flat-box" href=/lemonelf/categories/
                  
                  
                  
                    id="lemonelfcategories"
                  >
                  <i class='fas fa-folder-open fa-fw'></i>分类
                </a>
                
              </li>
            
          
          
            
            
              <li>
                <a class="menuitem flat-box" href=/lemonelf/tags/
                  
                  
                  
                    id="lemonelftags"
                  >
                  <i class='fas fa-tags fa-fw'></i>标签
                </a>
                
              </li>
            
          
          
            
            
              <li>
                <a class="menuitem flat-box" href=/lemonelf/archives/
                  
                  
                  
                    id="lemonelfarchives"
                  >
                  <i class='fas fa-archive fa-fw'></i>归档
                </a>
                
              </li>
            
          
          
            
            
              <li>
                <a class="menuitem flat-box" href=/lemonelf/friends/
                  
                  
                  
                    id="lemonelffriends"
                  >
                  <i class='fas fa-link fa-fw'></i>友链
                </a>
                
              </li>
            
          
          
            
            
              <li>
                <a class="menuitem flat-box" href=/lemonelf/about/
                  
                  
                  
                    id="lemonelfabout"
                  >
                  <i class='fas fa-info-circle fa-fw'></i>关于
                </a>
                
              </li>
            
          
          
				</ul>
			</div>

      <div class="m_search">
        <form name="searchform" class="form u-search-form">
          <i class="icon fas fa-search fa-fw"></i>
          <input type="text" class="input u-search-input" placeholder="Search..." />
        </form>
      </div>

			<ul class='switcher nav-list-h'>
				
					<li><a class="s-search fas fa-search fa-fw" target="_self" href='javascript:void(0)'></a></li>
				
				<li>
          <a class="s-menu fas fa-bars fa-fw" target="_self" href='javascript:void(0)'></a>
          <ul class="menu-phone list-v navigation white-box">
            
              
            
              <li>
                <a class="menuitem flat-box" href=/lemonelf/categories/
                  
                  
                  
                    id="lemonelfcategories"
                  >
                  <i class='fas fa-folder-open fa-fw'></i>分类
                </a>
                
              </li>
            
          
            
              
            
              <li>
                <a class="menuitem flat-box" href=/lemonelf/tags/
                  
                  
                  
                    id="lemonelftags"
                  >
                  <i class='fas fa-tags fa-fw'></i>标签
                </a>
                
              </li>
            
          
            
              
            
              <li>
                <a class="menuitem flat-box" href=/lemonelf/archives/
                  
                  
                  
                    id="lemonelfarchives"
                  >
                  <i class='fas fa-archive fa-fw'></i>归档
                </a>
                
              </li>
            
          
            
              
            
              <li>
                <a class="menuitem flat-box" href=/lemonelf/friends/
                  
                  
                  
                    id="lemonelffriends"
                  >
                  <i class='fas fa-link fa-fw'></i>友链
                </a>
                
              </li>
            
          
            
              
            
              <li>
                <a class="menuitem flat-box" href=/lemonelf/about/
                  
                  
                  
                    id="lemonelfabout"
                  >
                  <i class='fas fa-info-circle fa-fw'></i>关于
                </a>
                
              </li>
            
          
            
          </ul>
        </li>
			</ul>
		</div>
	</div>
  </div>
</header>

  </div>
  


  <div class="l_body nocover">
    <div class='body-wrapper' id="pjax-container">
      
        <!--此文件用来存放一些不方便取值的变量-->
<!--思路大概是将值藏到重加载的区域内-->



<div id="pjax-data" style="display: none">
  <div id="pjax-ispage">true</div>
  <div id="pjax-pageTitle">前端知识面试汇总</div>
  <div id="pjax-enable-cover">true</div>
  <div id="pjax-permalink">https://missglobefish.gitee.io/lemonelf/2020/08/13/%E5%89%8D%E7%AB%AF%E7%9F%A5%E8%AF%86%E9%9D%A2%E8%AF%95%E6%B1%87%E6%80%BB/</div>
  
  <div id="valine-path">none</div>
  <div id="valine-placeholder">none</div>
  
  
</div>


<script>
  // 处理封面 此时 jquery 还没加载
  if ("none" == "none") { // 移除封面
    document.getElementsByClassName('cover')[0].style.display = "none";
    document.getElementsByClassName('l_body')[0].classList.add("nocover");
    document.getElementsByClassName('l_header', 'cover-wrapper')[0].classList.add("show");
  } else {
    if ("none" == "blog") { // 半屏
      document.getElementsByClassName('cover')[0].classList.remove("full");
      document.getElementsByClassName('cover')[0].classList.add("half");
      document.getElementsByClassName('scroll-down')[0].style.display = "none";
    } else if ("none" == "docs") { // 全屏
      document.getElementsByClassName('cover')[0].classList.remove("half");
      document.getElementsByClassName('cover')[0].classList.add("full");
      document.getElementsByClassName('scroll-down')[0].style.display = "";
    }
    document.getElementsByClassName('cover')[0].style.display = "";
    document.getElementsByClassName('l_body', 'show')[0].classList.remove("nocover");
    document.getElementsByClassName('l_header', 'cover-wrapper')[0].classList.remove("show");
  }
</script>

      
      

<div class='l_main'>
  

  
    <article id="post" class="post white-box reveal shadow article-type-post" itemscope itemprop="blogPost">
      


  <section class='meta'>
    
      
      
        <a title='前端知识面试汇总' href='/lemonelf/2020/08/13/%E5%89%8D%E7%AB%AF%E7%9F%A5%E8%AF%86%E9%9D%A2%E8%AF%95%E6%B1%87%E6%80%BB/'><img class='thumbnail' src='https://img.vim-cn.com/17/0c7b02722686d1527a1df807dae0794d995860.png'></a>
      
      <div class="meta" id="header-meta">
        
          
  <h1 class="title">
    <a href="/lemonelf/2020/08/13/%E5%89%8D%E7%AB%AF%E7%9F%A5%E8%AF%86%E9%9D%A2%E8%AF%95%E6%B1%87%E6%80%BB/">
      前端知识面试汇总
    </a>
  </h1>


        
        <div class='new-meta-box'>
          
            
          
            
              
<div class='new-meta-item author'>
  <a class='author' href="/" rel="nofollow">
    <img no-lazy src="https://pic4.zhimg.com/80/v2-52584915d42d676148e2c302f4e87382_hd.jpg">
    <p>MissGlobeFish</p>
  </a>
</div>

            
          
            
              
  
  <div class='new-meta-item category'>
    <a href='/lemonelf/categories/%E5%85%B6%E4%BB%96/' rel="nofollow">
      <i class="fas fa-folder-open fa-fw" aria-hidden="true"></i>
      <p>其他</p>
    </a>
  </div>


            
          
            
              <div class="new-meta-item date">
  <a class='notlink'>
    <i class="fas fa-calendar-alt fa-fw" aria-hidden="true"></i>
    <p>发布于：2020-08-13</p>
  </a>
</div>

            
          
            
              

            
          
        </div>
        
          <hr>
        
      </div>
    
  </section>


      <section class="article typo">
        <div class="article-entry" itemprop="articleBody">
          
          
          <p>Sometimes you have to reach into someone else’s world to find out what’s missing in your own.</p>
<a id="more"></a>

<blockquote>
<p><strong>综合</strong></p>
</blockquote>
<p><code>HTML &amp; CSS</code>: 对 Web 标准的理解、浏览器内核差异、兼容性、hack、CSS 基本功：布局、盒子模型、选择器优先级及使用、HTML5、CSS3、移动端适应。</p>
<p><code>JavaScript</code>: 数据类型、面向对象、继承、闭包、插件、作用域、跨域、原型链、模块化、自定义事件、内存泄漏、事件机制、异步装载回调、模板引擎、Nodejs、JSON、ajax 等。</p>
<p><code>其他</code>: HTTP、安全、正则、优化、重构、响应式、移动端、团队协作、可维护、SEO、UED、架构、职业生涯 </p>
<blockquote>
<p><strong>Vue 方向</strong></p>
</blockquote>
<h4 id="1-MVVM-开发模式"><a href="#1-MVVM-开发模式" class="headerlink" title="1. MVVM 开发模式"></a>1. MVVM 开发模式</h4><p><code>MVVM</code> 分为 <code>Model</code>、<code>View</code>、<code>ViewModel</code> 三者。<br><code>Model</code> 代表数据模型，数据和业务逻辑都在 <code>Model</code> 层中定义；<br><code>View</code> 代表 <code>UI</code> 视图，负责数据的展示；<br><code>ViewModel</code> 负责监听 <code>Model</code> 中数据的改变并且控制视图的更新，处理用户交互操作；<br><code>Model</code> 和 <code>View</code> 并无直接关联，而是通过 <code>ViewModel</code> 来进行联系的，<code>Model</code> 和 <code>ViewModel</code> 之间有着双向数据绑定的联系。<br>因此当 <code>Model</code> 中的数据改变时会触发 <code>View</code> 层的刷新，<code>View</code> 中由于用户交互操作而改变的数据也会在 <code>Model</code> 中同步。<br>这种模式实现了 <code>Model</code> 和 <code>View</code> 的数据自动同步，因此开发者只需要专注对数据的维护操作即可，而不需要自己操作 <code>dom</code>。</p>
<h4 id="2-v-if-和-v-show-的区别"><a href="#2-v-if-和-v-show-的区别" class="headerlink" title="2. v-if 和 v-show 的区别"></a>2. v-if 和 v-show 的区别</h4><p><code>v-show</code> 仅仅控制元素的显示方式，将 <code>display</code> 属性在 <code>block</code> 和 <code>none</code> 来回切换；<br>而 <code>v-if</code> 会控制这个 <code>DOM</code> 节点的存在与否。<br>当我们需要经常切换某个元素的显示/隐藏时，使用 <code>v-show</code> 会更加节省性能上的开销；<br>当只需要一次显示或隐藏时，使用 <code>v-if</code> 更加合理。</p>
<h4 id="3-Vue-的响应式原理"><a href="#3-Vue-的响应式原理" class="headerlink" title="3. Vue 的响应式原理"></a>3. Vue 的响应式原理</h4><p>当一个 <code>Vue</code> 实例创建时，<code>vue</code> 会遍历 <code>data</code> 选项的属性，<br>用 <code>Object.defineProperty</code> 将它们转为 <code>getter/setter</code> 并且在内部追踪相关依赖，在属性被访问和修改时通知变化。<br>每个组件实例都有相应的 <code>watcher</code> 程序实例，它会在组件渲染的过程中把属性记录为依赖，<br>之后当依赖项的 <code>setter</code> 被调用时，会通知 <code>watcher</code> 重新计算，从而致使它关联的组件得以更新。<br><img src="/lemonElf/img/studyImg/vue01.png" alt="vue01"></p>
<h4 id="4-Vue-在组件间的通信"><a href="#4-Vue-在组件间的通信" class="headerlink" title="4. Vue 在组件间的通信"></a>4. Vue 在组件间的通信</h4><p>假设有一个输入框组件，用户输入时，同步父组件页面中的数据<br>具体思路：父组件通过 <code>props</code> 传值给子组件，子组件通过 <code>$emit</code> 来通知父组件修改相应的 <code>props</code> 值<br>具体实现如下：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> Vue <span class="keyword">from</span> <span class="string">&#x27;vue&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> component = &#123;</span><br><span class="line">  props: [<span class="string">&#x27;value&#x27;</span>],</span><br><span class="line">  template: <span class="string">`</span></span><br><span class="line"><span class="string">    &lt;div&gt;</span></span><br><span class="line"><span class="string">      &lt;input type=&quot;text&quot; @input=&quot;handleInput&quot; :value=&quot;value&quot;&gt;</span></span><br><span class="line"><span class="string">    &lt;/div&gt;</span></span><br><span class="line"><span class="string">  `</span>,</span><br><span class="line">  data () &#123;</span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,</span><br><span class="line">  methods: &#123;</span><br><span class="line">    handleInput (e) &#123;</span><br><span class="line">      <span class="built_in">this</span>.$emit(<span class="string">&#x27;input&#x27;</span>, e.target.value)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> Vue(&#123;</span><br><span class="line">  components: &#123;</span><br><span class="line">    CompOne: component</span><br><span class="line">  &#125;,</span><br><span class="line">  el: <span class="string">&#x27;#root&#x27;</span>,</span><br><span class="line">  template: <span class="string">`</span></span><br><span class="line"><span class="string">    &lt;div&gt;</span></span><br><span class="line"><span class="string">      &lt;comp-one :value1=&quot;value&quot; @input=&quot;value = arguments[0]&quot;&gt;&lt;/comp-one&gt;</span></span><br><span class="line"><span class="string">    &lt;/div&gt;</span></span><br><span class="line"><span class="string">  `</span>,</span><br><span class="line">  data () &#123;</span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">      value: <span class="string">&#x27;123&#x27;</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>

<p>可以看到，当输入数据时，父子组件中的数据是同步改变的：</p>
<p><img src="/lemonElf/img/studyImg/vue02.png" alt="vue02"><br><img src="/lemonElf/img/studyImg/vue03.png" alt="vue03"></p>
<p>我们在父组件中做了两件事，一是给子组件传入 <code>props</code>，二是监听 <code>input</code> 事件并同步自己的 <code>value</code> 属性。<br>那么这两步操作能否再精简一下呢？答案是可以的，你只需要修改父组件：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">template: <span class="string">`</span></span><br><span class="line"><span class="string">    &lt;div&gt;</span></span><br><span class="line"><span class="string">        &lt;!--&lt;comp-one :value1=&quot;value&quot; @input=&quot;value = arguments[0]&quot;&gt;&lt;/comp-one&gt;--&gt;</span></span><br><span class="line"><span class="string">        &lt;comp-one v-model=&quot;value&quot;&gt;&lt;/comp-one&gt;</span></span><br><span class="line"><span class="string">    &lt;/div&gt;</span></span><br><span class="line"><span class="string">`</span></span><br></pre></td></tr></table></figure>
<p><code>v-model</code> 实际上会帮我们完成上面的两步操作。</p>
<h4 id="5-Vue-的组件为什么要-export-default"><a href="#5-Vue-的组件为什么要-export-default" class="headerlink" title="5. Vue 的组件为什么要 export default"></a>5. Vue 的组件为什么要 export default</h4><p><code>Vue</code> 是通过 <code>webpack</code> 实现的模块化，因此可以使用 <code>import</code> 来引入模块，例如：</p>
<p><img src="/lemonElf/img/studyImg/vue08.png" alt="vue02"></p>
<p>此外，你还可以在 <code>bulid/webpack.base.conf.js</code> 文件中修改相关配置：</p>
<p><img src="/lemonElf/img/studyImg/vue09.png" alt="vue03"></p>
<p>意思是，你的模块可以省略 “<code>.js</code>“，”<code>.vue</code>“，“<code>.json</code>” 后缀，<code>weebpack</code> 会在之后自动添加上；可以用 “ <code>@</code> “ 符号代替 “ <code>src</code> “ 字符串等。</p>
<p><code>export</code> 用来导出模块，<code>Vue</code> 的单文件组件通常需要导出一个对象，这个对象是 <code>Vue</code> 实例的选项对象，以便于在其它地方可以使用 <code>import</code> 引入。<br>而 <code>new Vue()</code> 相当于一个构造函数，在入口文件 <code>main.js</code> 构造根组件的同时，如果根组件还包含其它子组件，那么 <code>Vue</code> 会通过引入的选项对象构造其对应的 <code>Vue</code> 实例，最终形成一棵组件树。</p>
<p><code>export</code> 和 <code>export default</code> 的区别在于：<code>export</code> 可以导出多个命名模块，例如：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//demo1.js</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> str = <span class="string">&#x27;hello world&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="function"><span class="keyword">function</span> <span class="title">f</span>(<span class="params">a</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> a+<span class="number">1</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>对应的引入方式：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//demo2.js</span></span><br><span class="line"><span class="keyword">import</span> &#123; str, f &#125; <span class="keyword">from</span> <span class="string">&#x27;demo1&#x27;</span></span><br></pre></td></tr></table></figure>

<p><code>export default</code> 只能导出一个默认模块，这个模块可以匿名，例如：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//demo1.js</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    a: <span class="string">&#x27;hello&#x27;</span>,</span><br><span class="line">    b: <span class="string">&#x27;world&#x27;</span>      </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>对应的引入方式：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//demo2.js</span></span><br><span class="line"><span class="keyword">import</span> obj <span class="keyword">from</span> <span class="string">&#x27;demo1&#x27;</span></span><br></pre></td></tr></table></figure>
<p>引入的时候可以给这个模块取任意名字，例如 “ <code>obj</code> “，且不需要用大括号括起来。</p>
<h4 id="6-Vue-中给-data-中的对象属性添加一个新的属性时会发生什么，如何解决？"><a href="#6-Vue-中给-data-中的对象属性添加一个新的属性时会发生什么，如何解决？" class="headerlink" title="6. Vue 中给 data 中的对象属性添加一个新的属性时会发生什么，如何解决？"></a>6. Vue 中给 data 中的对象属性添加一个新的属性时会发生什么，如何解决？</h4><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">ul</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">li</span> <span class="attr">v-for</span>=<span class="string">&quot;value in obj&quot;</span> <span class="attr">:key</span>=<span class="string">&quot;value&quot;</span>&gt;</span></span><br><span class="line">            &#123;&#123;value&#125;&#125;</span><br><span class="line">        <span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">ul</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">button</span> @<span class="attr">click</span>=<span class="string">&quot;addObjB&quot;</span>&gt;</span>添加 obj.b<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="javascript">    <span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span><br><span class="line">        data () &#123;</span><br><span class="line"><span class="javascript">            <span class="keyword">return</span> &#123;</span></span><br><span class="line">                obj: &#123;</span><br><span class="line"><span class="javascript">                    a: <span class="string">&#x27;obj.a&#x27;</span></span></span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;,</span><br><span class="line">        methods: &#123;</span><br><span class="line">            addObjB () &#123;</span><br><span class="line"><span class="javascript">                <span class="built_in">this</span>.obj.b = <span class="string">&#x27;obj.b&#x27;</span></span></span><br><span class="line"><span class="javascript">                <span class="built_in">console</span>.log(<span class="built_in">this</span>.obj)</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">style</span>&gt;</span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>点击 <code>button</code> 会发现，<code>obj.b</code> 已经成功添加，但是视图并未刷新：</p>
<p><img src="/lemonElf/img/studyImg/vue04.png" alt="vue04"></p>
<p>原因在于在 Vue 实例创建时，<code>obj.b</code> 并未声明，因此就没有被 Vue 转换为响应式的属性，自然就不会触发视图的更新<br>这时就需要使用 Vue 的全局 <code>api $set()</code>：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">addObjB () &#123;</span><br><span class="line">    <span class="comment">// this.obj.b = &#x27;obj.b&#x27;</span></span><br><span class="line">    <span class="built_in">this</span>.$set(<span class="built_in">this</span>.obj, <span class="string">&#x27;b&#x27;</span>, <span class="string">&#x27;obj.b&#x27;</span>)</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="built_in">this</span>.obj)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><code>$set()</code> 方法相当于手动的去把 <code>obj.b</code> 处理成一个响应式的属性，此时视图也会跟着改变了：</p>
<p><img src="/lemonElf/img/studyImg/vue05.png" alt="vue05"></p>
<h4 id="7-delete-和-Vue-delete-删除数组的区别"><a href="#7-delete-和-Vue-delete-删除数组的区别" class="headerlink" title="7. delete 和 Vue.delete 删除数组的区别"></a>7. delete 和 Vue.delete 删除数组的区别</h4><p><code>delete</code> 只是被删除的元素变成了 <code>empty/undefined</code> 其他的元素的键值还是不变。<br><code>Vue.delete</code> 直接删除了数组 改变了数组的键值。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>]</span><br><span class="line"><span class="keyword">var</span> b=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>]</span><br><span class="line"><span class="keyword">delete</span> a[<span class="number">1</span>]</span><br><span class="line"><span class="built_in">console</span>.log(a)</span><br><span class="line"></span><br><span class="line"><span class="built_in">this</span>.$delete(b,<span class="number">1</span>)</span><br><span class="line"><span class="built_in">console</span>.log(b)</span><br></pre></td></tr></table></figure>
<p><img src="/lemonElf/img/studyImg/vue06.png" alt="vue06"><br><img src="/lemonElf/img/studyImg/vue07.png" alt="vue07"></p>
<h4 id="8-vue-js-判断设备是手机端还是pc端"><a href="#8-vue-js-判断设备是手机端还是pc端" class="headerlink" title="8. vue.js 判断设备是手机端还是pc端"></a>8. vue.js 判断设备是手机端还是pc端</h4><p>在 <code>router/index.js</code> 中有配置两个页面。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">new</span> Router(&#123;</span><br><span class="line">    mode: <span class="string">&#x27;history&#x27;</span>,</span><br><span class="line">    routes: [</span><br><span class="line">        &#123;</span><br><span class="line">            path: <span class="string">&#x27;&#x27;</span>,</span><br><span class="line">            redirect: <span class="string">&#x27;/pc_index&#x27;</span></span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">            path: <span class="string">&quot;/pc_index&quot;</span>, <span class="comment">// pc端首页</span></span><br><span class="line">            name: PcIndex,</span><br><span class="line">            component: PcIndex</span><br><span class="line">        &#125;,</span><br><span class="line">        &#123;</span><br><span class="line">            path: <span class="string">&#x27;/m_index&#x27;</span>, <span class="comment">// 手机端首页</span></span><br><span class="line">            name: MIndex,</span><br><span class="line">            component: MIndex</span><br><span class="line">        &#125;</span><br><span class="line">    ]</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>在 <code>App.vue</code> 的 <code>mounted</code> 方法中对设置进行判断，如下:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">mounted() &#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="built_in">this</span>._isMobile()) &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">&quot;手机端&quot;</span>);</span><br><span class="line">        <span class="built_in">this</span>.$router.replace(<span class="string">&#x27;/m_index&#x27;</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">&quot;pc端&quot;</span>);</span><br><span class="line">        <span class="built_in">this</span>.$router.replace(<span class="string">&#x27;/pc_index&#x27;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>其中 <code> _isMobile()</code> 方法如下:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">_isMobile() &#123;</span><br><span class="line">    <span class="keyword">let</span> flag = navigator.userAgent.match(<span class="regexp">/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i</span>)</span><br><span class="line">    <span class="keyword">return</span> flag;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h4 id="9-uniApp-如何获取-globalData-全局变量"><a href="#9-uniApp-如何获取-globalData-全局变量" class="headerlink" title="9. uniApp 如何获取 globalData 全局变量"></a>9. uniApp 如何获取 globalData 全局变量</h4><p>App.vue</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    onLaunch: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">&#x27;App Launch&#x27;</span>);</span><br><span class="line">    &#125;,</span><br><span class="line">    onShow: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">&#x27;App Show&#x27;</span>);</span><br><span class="line">    &#125;,</span><br><span class="line">    onHide: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">&#x27;App Hide&#x27;</span>);</span><br><span class="line">    &#125;,</span><br><span class="line">    globalData:&#123;</span><br><span class="line">        url: <span class="string">&#x27;www.baidu.com&#x27;</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>xxx.vue</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    onLoad() &#123;</span><br><span class="line">        <span class="keyword">var</span> globalData = getApp().globalData.url</span><br><span class="line">        <span class="built_in">console</span>.log(globalData)  </span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<blockquote>
<p><strong>JS 基础相关</strong></p>
</blockquote>
<h4 id="1-jQuery-获取的-dom-对象和原生的-dom-对象有何区别？"><a href="#1-jQuery-获取的-dom-对象和原生的-dom-对象有何区别？" class="headerlink" title="1. jQuery 获取的 dom 对象和原生的 dom 对象有何区别？"></a>1. jQuery 获取的 dom 对象和原生的 dom 对象有何区别？</h4><p>js 原生获取的 dom 是一个对象，jQuery 对象就是一个数组对象，其实就是选择出来的元素的数组集合，所以说他们两者是不同的对象类型不等价。</p>
<p>@ 原生 DOM 对象转 jQuery 对象：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> box = <span class="built_in">document</span>.getElementById(<span class="string">&#x27;box&#x27;</span>);</span><br><span class="line"><span class="keyword">var</span> $box = $(box);</span><br></pre></td></tr></table></figure>
<p>@ jQuery 对象转原生 DOM 对象：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> $box = $(<span class="string">&#x27;#box&#x27;</span>);</span><br><span class="line"><span class="keyword">var</span> box = $box[<span class="number">0</span>];</span><br></pre></td></tr></table></figure>

<h4 id="2-jQuery-如何扩展自定义方法"><a href="#2-jQuery-如何扩展自定义方法" class="headerlink" title="2. jQuery 如何扩展自定义方法"></a>2. jQuery 如何扩展自定义方法</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">(jQuery.fn.myMethod=<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">   alert(<span class="string">&#x27;myMethod&#x27;</span>);</span><br><span class="line">&#125;)</span><br><span class="line"><span class="comment">// 或者：</span></span><br><span class="line">(<span class="function"><span class="keyword">function</span> (<span class="params">$</span>) </span>&#123;</span><br><span class="line">        $.fn.extend(&#123;</span><br><span class="line">            myMethod : <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">                alert(<span class="string">&#x27;myMethod&#x27;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;)</span><br><span class="line">&#125;)(jQuery)</span><br></pre></td></tr></table></figure>
<p>使用：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$(<span class="string">&quot;#div&quot;</span>).myMethod();</span><br></pre></td></tr></table></figure>

<h4 id="3-函数声明与表达式"><a href="#3-函数声明与表达式" class="headerlink" title="3. 函数声明与表达式"></a>3. 函数声明与表达式</h4><p>在 <code>JavaScript</code> 中定义一个函数有四种方式：</p>
<ol>
<li>函数声明</li>
<li>函数表达式</li>
<li>ES6 里箭头函数</li>
<li>new Function()</li>
</ol>
<p>（ 一 ） 什么是函数声明（ Function Declaration ）？</p>
<p>A. 解释：<br><code>Function Declaration</code> 可以定义命名的函数变量，而无需给变量赋值。<br><code>Function Declaration</code> 是一种独立的结构，不能嵌套在非功能模块中。<br>可以将它类比为 <code>Variable Declaration</code>（变量声明）。<br>就像 <code>Variable Declaration</code> 必须以“ <code>var</code> ”开头一样，<code>Function Declaration</code> 必须以“ <code>function</code> ”开头。</p>
<p>B. 语法： </p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> 函数名 (<span class="params"> 参数 </span>) </span>&#123;</span><br><span class="line">    要执行的代码（函数体）</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>C. 调用：</p>
<ol>
<li>函数名( 参数 )</li>
<li>函数名.call( 函数名,参数 )</li>
<li>函数名.apply( 函数名,[参数] )</li>
<li>new 函数名( 参数 )</li>
<li>定时器</li>
<li>把函数声明变成函数表达式再调用</li>
<li>ES6 里的模版字符串</li>
</ol>
<p>（ 二 ） 什么是函数表达式（ Function Expression ）？</p>
<p>A. 解释：<br><code>Function Expression</code> 将函数定义为表达式语句（通常是变量赋值）的一部分。<br>通过 <code>Function Expression</code> 定义的函数可以是命名的，也可以是匿名的。<br><code>Function Expression</code> 不能以“ <code>function</code> ”开头。</p>
<p>B. 语法：  </p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span>/<span class="keyword">let</span>/<span class="keyword">const</span> 变量 = <span class="function"><span class="keyword">function</span> (<span class="params"> 参数 </span>) </span>&#123;</span><br><span class="line">    要执行的代码（函数体）</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>C. 调用：</p>
<ol>
<li>函数名( 参数 )</li>
<li>函数名.call( 函数名,参数 )</li>
<li>函数名.apply( 函数名,[参数] )</li>
<li>new 函数名( 参数 )</li>
<li>直接在后面加上一对小括号</li>
<li>定时器</li>
<li>ES6 里的模版字符串</li>
<li>以被赋值的形式出现（ 根据具体形式调用 ）</li>
</ol>
<p>（ 三 ） 函数声明与函数表达式的区别</p>
<ol>
<li>以函数声明的方法定义的函数,函数名是必须的,而函数表达式的函数名是可选的。（ 函数声明整体会被提升到当前作用域的顶部，函数表达式也提升到顶部但是只有其变量名提升 ）</li>
<li>以函数声明的方法定义的函数,函数可以在函数声明之前调用,而函数表达式的函数只能在声明之后调用。</li>
<li>以函数声明的方法定义的函数并不是真正的声明,它们仅仅可以出现在全局中,或者嵌套在其他的函数中,但是它们不能出现在循环,条件或者 try/catch/finally 中,而函数表达式可以在任何地方声明。换句话说，函数声明不是一个完整的语句，所以不能出现在 if-else,for 循环，finally，try catch 语句以及 with 语句中。</li>
<li>函数声明必须带有标识符（ 函数名称 ），函数表达式则可以省略。（ 表达式里的名字不能在函数外面用，只能在函数内部用；函数有一个 name 属性，指向紧跟在 function 关键字之后的那个函数名。如果函数表达式没有名字，那 name 属性指向变量名 ）</li>
<li>JS 程序在正式执行之前，会将所有 var 声明的变量和 function 声明的函数，预读到所在作用域的顶部，var 声明只是将声明提前，赋值仍然保留在原位置，function 声明，会将函数名称和函数体都提前，这个过程也被叫做“ 预解析 ”或者“ 预编译 ”。（ 函数声明会被预解析，函数表达式不会 ）<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 1、名字</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 函数声明必需带名字</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params"></span>)</span>&#123;&#125;;</span><br><span class="line"><span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;&#125;;     <span class="comment">//报错，没有名字</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 函数表达式可以没有名字</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> fn1 = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;&#125;;</span><br><span class="line">( <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;&#125; );</span><br><span class="line">!<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 表达式名字的作用</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> fn2 = <span class="function"><span class="keyword">function</span> <span class="title">newFn</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log( newFn ); <span class="comment">//可以在这里面用。有一个作用就是在这里用递归</span></span><br><span class="line">&#125;;</span><br><span class="line">fn2();</span><br><span class="line">newFn();  <span class="comment">//报错，不能在外面用</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//name 属性</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(</span><br><span class="line">    fn.name,    <span class="comment">//fn</span></span><br><span class="line">    fn1.name,   <span class="comment">//fn1   表达式没有名字，name属性指向表达式变量名</span></span><br><span class="line">    fn2.name    <span class="comment">//newFn</span></span><br><span class="line">);      </span><br><span class="line"></span><br><span class="line"><span class="comment">//2、预解析</span></span><br><span class="line"></span><br><span class="line">fn3();</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn3</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;fn3&#x27;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">fn4();    <span class="comment">//报错，不会被预解析</span></span><br><span class="line"><span class="keyword">let</span> fn4=<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;fn4&#x27;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

</li>
</ol>
<p>（ 四 ） 函数声明不能直接调用</p>
<ol>
<li>小括号里只能放表达式，不能放语句。</li>
<li>function 关键字即可以当作语句，也可以当作表达式。但 js 规定 function 关键字出现在行首，一律解释成语句</li>
</ol>
<p>【 解决方法 】：</p>
<ol>
<li>不要让 function 出现在行首</li>
<li>用括号把 function 主体括起来，转成表达式。后面加括号运行</li>
<li>借助运算符（new + - ! ~ typeof , &amp;&amp; ||…）（ 因为运算符会把表达式执行，执行后得出结果了才能运算 ）</li>
</ol>
<h4 id="4-JavaScript-语言对原型对象的理解"><a href="#4-JavaScript-语言对原型对象的理解" class="headerlink" title="4. JavaScript 语言对原型对象的理解"></a>4. JavaScript 语言对原型对象的理解</h4><ol>
<li>无论什么时候，只要创建了一个新函数，就会根据一组特定的规则为该函数创建一个 <code>prototype</code> 属性，这个属性指向函数的原型对象（图6.1中的序号1）。</li>
<li>在默认情况下，所有原型对象都会自动获得一个 <code>constructor</code>（构造函数）属性，这个属性包含一个指向 <code>prototype</code> 属性所在函数的指针（图6.1中的序号2）。</li>
<li>创建了自定义的构造函数之后，其原型对象默认只会取得 <code>constructor</code> 属性；至于其他方法，则都是从 <code>Object</code> 继承而来。</li>
<li>当调用构造函数创建一个新实例后，该实例的内部将包含一个指针，指向构造函数的原型对象（图6.1中序号3，4）。</li>
</ol>
<p><img src="/lemonElf/img/studyImg/js01.png" alt="js01"></p>
<blockquote>
<p><strong>CSS 相关</strong></p>
</blockquote>
<blockquote>
<p><strong>网页优化相关</strong></p>
</blockquote>
<h4 id="1-如何优化-SPA-应用的首屏加载速度慢的问题？"><a href="#1-如何优化-SPA-应用的首屏加载速度慢的问题？" class="headerlink" title="1. 如何优化 SPA 应用的首屏加载速度慢的问题？"></a>1. 如何优化 SPA 应用的首屏加载速度慢的问题？</h4><p>a. 将公用的 JS 库通过 <code>script</code> 标签外部引入，减小 <code>app.bundel</code> 的大小，让浏览器并行下载资源文件，提高下载速度；<br>b. 在配置 路由时，页面和组件使用懒加载的方式引入，进一步缩小 <code>app.bundel</code> 的体积，在调用某个组件时再加载对应的 js 文件；<br>c. 加一个首屏 <code>loading</code> 图，提升用户体验；</p>
<h4 id="2-前端如何优化网站性能？"><a href="#2-前端如何优化网站性能？" class="headerlink" title="2. 前端如何优化网站性能？"></a>2. 前端如何优化网站性能？</h4><h6 id="A-减少-HTTP-请求数量"><a href="#A-减少-HTTP-请求数量" class="headerlink" title="A. 减少 HTTP 请求数量"></a>A. 减少 HTTP 请求数量</h6><p>在浏览器与服务器进行通信时，主要是通过 <code>HTTP</code> 进行通信。<br>浏览器与服务器需要经过三次握手，每次握手需要花费大量时间。<br>而且不同浏览器对资源文件并发请求数量有限（<a target="_blank" rel="noopener" href="http://www.stevesouders.com/blog/2008/03/20/roundup-on-parallel-connections/">不同浏览器允许并发数</a>），一旦 HTTP 请求数量达到一定数量，资源请求就存在等待状态，这是很致命的；<br>因此减少 <code>HTTP</code> 的请求数量可以很大程度上对网站性能进行优化。</p>
<ol>
<li>CSS Sprites：国内俗称 CSS 精灵，这是将多张图片合并成一张图片达到减少 HTTP 请求的一种解决方案，可以通过 CSS background 属性来访问图片内容。这种方案同时还可以减少图片总字节数。</li>
<li>合并 CSS 和 JS 文件：现在前端有很多工程化打包工具，如：grunt、gulp、webpack等。为了减少 HTTP 请求数量，可以通过这些工具再发布前将多个 CSS 或者 多个 JS 合并成一个文件。</li>
<li>采用 lazyLoad：俗称懒加载，可以控制网页上的内容在一开始无需加载，不需要发请求，等到用户操作真正需要的时候立即加载出内容。这样就控制了网页资源一次性请求数量。</li>
</ol>
<h6 id="B-控制资源文件加载优先级"><a href="#B-控制资源文件加载优先级" class="headerlink" title="B. 控制资源文件加载优先级"></a>B. 控制资源文件加载优先级</h6><p>浏览器在加载 <code>HTML</code> 内容时，是将 <code>HTML</code> 内容从上至下依次解析，解析到 <code>link</code> 或者 <code>script</code> 标签就会加载 <code>href</code> 或者 <code>src</code> 对应链接内容，<br>为了第一时间展示页面给用户，就需要将 <code>CSS</code> 提前加载，不要受 <code>JS</code> 加载影响。<br>一般情况下都是 <code>CSS</code> 在头部，<code>JS</code> 在底部。</p>
<ol>
<li>利用浏览器缓存：浏览器缓存是将网络资源存储在本地，等待下次请求该资源时，如果资源已经存在就不需要到服务器重新请求该资源，直接在本地读取该资源。</li>
<li>减少重排（Reflow）：重排是 DOM 的变化影响到了元素的几何属性（宽和高），浏览器会重新计算元素的几何属性，会使渲染树中受到影响的部分失效，浏览器会验证 DOM 树上的所有其它结点的 visibility 属性，这也是 Reflow 低效的原因。如果 Reflow 的过于频繁，CPU 使用率就会急剧上升。</li>
</ol>
<p>减少 <code>Reflow</code>，如果需要在 <code>DOM</code> 操作时添加样式，尽量使用 增加 <code>class</code> 属性，而不是通过 <code>style</code> 操作样式。</p>
<h6 id="C-减少-DOM-操作"><a href="#C-减少-DOM-操作" class="headerlink" title="C. 减少 DOM 操作"></a>C. 减少 <code>DOM</code> 操作</h6><h6 id="D-图标使用-IconFont-替换"><a href="#D-图标使用-IconFont-替换" class="headerlink" title="D. 图标使用 IconFont 替换"></a>D. 图标使用 <code>IconFont</code> 替换</h6><h4 id="3-网页从输入网址到渲染完成经历了哪些过程？"><a href="#3-网页从输入网址到渲染完成经历了哪些过程？" class="headerlink" title="3. 网页从输入网址到渲染完成经历了哪些过程？"></a>3. 网页从输入网址到渲染完成经历了哪些过程？</h4><ol>
<li>输入网址；</li>
<li>发送到 DNS 服务器，并获取域名对应的 web 服务器对应的 ip 地址；</li>
<li>与 web 服务器建立 TCP 连接；</li>
<li>浏览器向 web 服务器发送 http 请求；</li>
<li>web 服务器响应请求，并返回指定 url 的数据（或错误信息，或重定向的新的 url 地址）；</li>
<li>浏览器下载 web 服务器返回的数据及解析 html 源文件；</li>
<li>生成 DOM 树，解析 css 和 js，渲染页面，直至显示完成；</li>
</ol>
<blockquote>
<p><strong>浏览器相关</strong></p>
</blockquote>
<h4 id="1-谈谈-Cookie"><a href="#1-谈谈-Cookie" class="headerlink" title="1. 谈谈 Cookie"></a>1. 谈谈 Cookie</h4><p>@ <code>cookie</code> 虽然在持久保持客户端数据提供了方便，分担了服务器存储的负担，但还是有很多局限。</p>
<ol>
<li>IE6 或更低版本最多 20 个 cookie；</li>
<li>IE7 和之后的版本最后可以有 50 个 cookie；</li>
<li>Firefox 最多 50 个 cookie；</li>
<li>chrome 和 Safari 没有做硬性限制；</li>
<li>IE 和 Opera 会清理近期最少使用的 cookie，Firefox 会随机清理 cookie；</li>
<li>cookie 的最大大约为 4096 字节，为了兼容性，一般不能超过 4095 字节。</li>
</ol>
<p>@ <code>IE</code> 提供了一种存储可以持久化用户数据，叫做 <code>userdata</code>，从 <code>IE5.0</code> 就开始支持。<br>@ 每个数据最多 <code>128K</code>，每个域名下最多 <code>1M</code>。这个持久化数据放在缓存中，如果缓存没有清理，那么会一直存在。 </p>
<p>优点：极高的扩展性和可用性</p>
<ol>
<li>通过良好的编程，控制保存在 cookie 中的 session 对象的大小；</li>
<li>通过加密和安全传输技术（ SSL ），减少 cookie 被破解的可能性；</li>
<li>在 cookie 中不存放敏感数据，即使被盗也不会有重大损失；</li>
<li>控制 cookie 的生命期，使之不会永远有效。偷盗者很可能拿到一个过期的 cookie。</li>
</ol>
<p>缺点：</p>
<ol>
<li>Cookie 数量和长度的限制。每个 domain 最多只能有 20 条 cookie，每个 cookie 长度不能超过 4KB，否则会被截掉。在当今新的浏览器和客户端设备版本中，支持 8192 字节的 Cookie 大小已愈发常见。</li>
<li>用户配置为禁用。有些用户禁用了浏览器或客户端设备接收 Cookie 的能力，因此限制了这一功能；</li>
<li>由于在 HTTP 请求中的 cookie 是明文传递的，潜在的安全风险，Cookie 可能会被篡改；</li>
<li>有些状态不可能保存在客户端；</li>
<li>cooki e会被附加在每个 HTTP 请求中，所以无形中增加了流量。</li>
<li>cookie 一般不可跨域使用；</li>
<li>没有封装好的 setCookie 和 getCookie 方法，需要开发者自行封装。</li>
</ol>
<h4 id="2-浏览器缓存原理以及本地存储"><a href="#2-浏览器缓存原理以及本地存储" class="headerlink" title="2. 浏览器缓存原理以及本地存储"></a>2. 浏览器缓存原理以及本地存储</h4><p>@ 缓存从宏观上分为私有缓存和共享缓存，共享缓存就是那些能被各级代理缓存的缓存。<br>@ 私有缓存就是用户专享的，各级代理不能缓存的缓存。</p>
<p>缓存从微观上可以分为几类：<code>浏览器缓存</code>  <code>代理服务器缓存</code>  <code>CDN 缓存</code>  <code>数据库缓存</code>  <code>应用层缓存</code></p>
<p>这里主要对浏览器的缓存进行说明：</p>
<p><img src="/lemonElf/img/studyImg/else01.png" alt="else01"></p>
<h5 id="A-http-缓存"><a href="#A-http-缓存" class="headerlink" title="A. http 缓存"></a>A. http 缓存</h5><h6 id="a-强缓存"><a href="#a-强缓存" class="headerlink" title="a. 强缓存"></a>a. 强缓存</h6><ol>
<li>不会向服务器发送请求，直接从缓存中读取资源</li>
<li>请求返回 200 的状态码</li>
<li>在 chrome 控制台的 network 选项中可以看到 size 显示 from disk cache 或 from memory cache。</li>
</ol>
<p>@ <code>from memory cache</code> 代表使用内存中的缓存，<code>from disk cache</code> 则代表使用的是硬盘中的缓存，浏览器读取缓存的顺序为 <code>memory –&gt; disk</code>。<br>@ 在浏览器中，浏览器会在 <code>js</code> 和图片等文件解析执行后直接存入内存缓存中，那么当刷新页面时只需直接从内存缓存中读取( <code>from memory cache</code> )；<br>@ 而 <code>css</code> 文件则会存入硬盘文件中，所以每次渲染页面都需要从硬盘读取缓存( <code>from disk cache</code> )。</p>
<p><img src="/lemonElf/img/studyImg/else02.png" alt="else02"></p>
<p><code>Expires</code> 和 <code>Cache-Control</code> 两者对比：<br>@ 其实这两者差别不大，区别就在于 <code>Expires</code> 是 <code>http1.0</code> 的产物，<br>@ <code>Cache-Control</code> 是 <code>http1.1</code> 的产物，两者同时存在的话，<code>Cache-Control</code> 优先级高于 <code>Expires</code>。</p>
<h6 id="b-协商缓存"><a href="#b-协商缓存" class="headerlink" title="b. 协商缓存"></a>b. 协商缓存</h6><p>@ 协商缓存就是强制缓存失效后，浏览器携带缓存标识向服务器发起请求，由服务器根据缓存标识决定是否使用缓存的过程。<br>@ 协商缓存生效，返回 <code>304</code> 和 <code>Not Modified</code>。</p>
<p><img src="/lemonElf/img/studyImg/else03.png" alt="else03"></p>
<h6 id="b-1-Last-Modified-和-If-Modified-Since"><a href="#b-1-Last-Modified-和-If-Modified-Since" class="headerlink" title="b.1 Last-Modified 和 If-Modified-Since"></a>b.1 Last-Modified 和 If-Modified-Since</h6><p>@ 浏览器在第一次访问资源，服务器返回资源的同时，在 <code>response header</code> 中添加 <code>Last-Modified</code> 的 <code>header</code>，值是这个资源在服务器上的最后修改时间，浏览器接收后缓存文件和 <code>header</code> ；<br>@ 浏览器下一次请求这个资源，浏览器检测到有 <code>Last-Modified</code> 这个 <code>header</code>，于是添加 <code>If-Modified-Since</code> 这个 <code>header</code>，值就是 <code>Last-Modified</code> 中的值；<br>@ 服务器再次收到这个资源请求，会根据 <code>If-Modified-Since</code> 中的值与服务器中这个资源的最后修改时间对比，如果没有变化，返回 <code>304</code> 和空的响应体，直接从缓存读取，<br>@ 如果 <code>If-Modified-Since</code> 的时间小于服务器中这个资源的最后修改时间，说明文件有更新，于是返回新的资源文件和 <code>200</code>。</p>
<p>【缺点】某些服务端不能获取精确的修改时间。<br>【缺点】文件修改时间改了，但文件内容却没有变。</p>
<h6 id="b-2-ETag-和-If-None-Match"><a href="#b-2-ETag-和-If-None-Match" class="headerlink" title="b.2 ETag 和 If-None-Match"></a>b.2 ETag 和 If-None-Match</h6><p>@ <code>Etag</code> 是上一次加载资源时，服务器返回的 <code>response header</code>，是对该资源的一种唯一标识，只要资源有变化，<code>Etag</code> 就会重新生成。<br>@ 浏览器在下一次加载资源向服务器发送请求时，会将上一次返回的 <code>Etag</code> 值放到 <code>request header</code> 里的 <code>If-None-Match</code> 里，<br>@ 服务器只需要比较客户端传来的 <code>If-None-Match</code> 跟自己服务器上该资源的 <code>ETag</code> 是否一致，就能很好地判断资源相对客户端而言是否被修改过了。<br>@ 如果服务器发现 <code>ETag</code> 匹配不上，那么直接以常规 <code>GET 200</code> 回包形式将新的资源（ 当然也包括了新的 <code>ETag</code> ）发给客户端；<br>@ 如果 <code>ETag</code> 是一致的，则直接返回 <code>304</code> 知会客户端直接使用本地缓存即可。</p>
<h6 id="b-3-协商缓存两种方式的对比"><a href="#b-3-协商缓存两种方式的对比" class="headerlink" title="b.3 协商缓存两种方式的对比"></a>b.3 协商缓存两种方式的对比</h6><ol>
<li>首先在精确度上，Etag 要优于 Last-Modified，Last-Modified 的时间单位是秒，如果某个文件在 1 秒内改变了多次，那么他们的 Last-Modified 其实并没有体现出来修改，但是 Etag 每次都会改变确保了精度；如果是负载均衡的服务器，各个服务器生成的 Last-Modified 也有可能不一致。</li>
<li>性能上，Etag 要逊于 Last-Modified，毕竟 Last-Modified 只需要记录时间，而 Etag 需要服务器通过算法来计算出一个 hash 值。</li>
<li>优先级上，服务器校验优先考虑 Etag。</li>
</ol>

          
            <div class='article_footer'>
              
                
  

  

  

  


              
            </div>
          
        </div>
        
          


  <section class='meta' id="footer-meta">
    <div class='new-meta-box'>
      
        
          <div class="new-meta-item date" itemprop="dateUpdated" datetime="2021-05-11T21:42:55+08:00">
  <a class='notlink'>
    <i class="fas fa-edit fa-fw" aria-hidden="true"></i>
    <p>更新于：2021-05-11</p>
  </a>
</div>

        
      
        
          
  
  <div class="new-meta-item meta-tags"><a class="tag" href="/lemonelf/tags/%E5%85%B6%E4%BB%96/" rel="nofollow"><i class="fas fa-hashtag fa-fw" aria-hidden="true"></i><p>其他</p></a></div>


        
      
        
          

        
      
        
          
  <div class="new-meta-item share -mob-share-list">
  <div class="-mob-share-list share-body">
    
      
        <a class="-mob-share-qq" title="" rel="external nofollow noopener noreferrer noopener"
          
          target="_blank" href="http://connect.qq.com/widget/shareqq/index.html?url=https://missglobefish.gitee.io/lemonelf/2020/08/13/%E5%89%8D%E7%AB%AF%E7%9F%A5%E8%AF%86%E9%9D%A2%E8%AF%95%E6%B1%87%E6%80%BB/&title=前端知识面试汇总 - 河豚吞吞&pics=https://img.vim-cn.com/17/0c7b02722686d1527a1df807dae0794d995860.png&summary=Sometimes you have to reach into someone else’s world to find out what’s missing in your own."
          
          >
          
            <img src="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/logo/128/qq.png">
          
        </a>
      
    
      
        <a class="-mob-share-qzone" title="" rel="external nofollow noopener noreferrer noopener"
          
          target="_blank" href="https://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=https://missglobefish.gitee.io/lemonelf/2020/08/13/%E5%89%8D%E7%AB%AF%E7%9F%A5%E8%AF%86%E9%9D%A2%E8%AF%95%E6%B1%87%E6%80%BB/&title=前端知识面试汇总 - 河豚吞吞&pics=https://img.vim-cn.com/17/0c7b02722686d1527a1df807dae0794d995860.png&summary=Sometimes you have to reach into someone else’s world to find out what’s missing in your own."
          
          >
          
            <img src="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/logo/128/qzone.png">
          
        </a>
      
    
      
        <a class="-mob-share-weibo" title="" rel="external nofollow noopener noreferrer noopener"
          
          target="_blank" href="http://service.weibo.com/share/share.php?url=https://missglobefish.gitee.io/lemonelf/2020/08/13/%E5%89%8D%E7%AB%AF%E7%9F%A5%E8%AF%86%E9%9D%A2%E8%AF%95%E6%B1%87%E6%80%BB/&title=前端知识面试汇总 - 河豚吞吞&pics=https://img.vim-cn.com/17/0c7b02722686d1527a1df807dae0794d995860.png&summary=Sometimes you have to reach into someone else’s world to find out what’s missing in your own."
          
          >
          
            <img src="https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/logo/128/weibo.png">
          
        </a>
      
    
  </div>
</div>



        
      
    </div>
  </section>


        
        
          <div class="prev-next">
            
              <a class='prev' href='/lemonelf/2020/08/13/%E5%A3%B0%E6%98%8E%E4%B8%8E%E8%A1%A8%E8%BE%BE%E5%BC%8F/'>
                <p class='title'><i class="fas fa-chevron-left" aria-hidden="true"></i>声明与表达式</p>
                <p class='content'>If You Stay Positive, You Have A Shot At A Silver Lining.


目前各大浏览器基本上都支持 ES6 的新特性，其中 Chrome 和 Fi...</p>
              </a>
            
            
              <a class='next' href='/lemonelf/2020/08/13/%E5%88%97%E4%B8%80%E4%BB%BD%E5%89%8D%E7%AB%AF%E7%9F%A5%E8%AF%86%E6%9E%B6%E6%9E%84%E5%9B%BE/'>
                <p class='title'>列一份前端知识架构图<i class="fas fa-chevron-right" aria-hidden="true"></i></p>
                <p class='content'>Beauty is in the eye of the beholder.


前端的知识在总体上分成基础部分和实践部分，基础部分包含了 JavaScript 语言 、 CSS 和 HTML 以...</p>
              </a>
            
          </div>
        
      </section>
    </article>
  




<!-- 根据页面mathjax变量决定是否加载MathJax数学公式js -->


</div>
<aside class='l_side'>
  
  

  
    
    



  <section class="widget toc-wrapper shadow desktop mobile" id="toc-div" >
    
  <header>
    
      <i class="fas fa-list fa-fw" aria-hidden="true"></i><span class='name'>本文目录</span>
    
  </header>


    <div class='content'>
        <ol class="toc"><li class="toc-item toc-level-4"><a class="toc-link" href="#1-MVVM-%E5%BC%80%E5%8F%91%E6%A8%A1%E5%BC%8F"><span class="toc-text">1. MVVM 开发模式</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2-v-if-%E5%92%8C-v-show-%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-text">2. v-if 和 v-show 的区别</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#3-Vue-%E7%9A%84%E5%93%8D%E5%BA%94%E5%BC%8F%E5%8E%9F%E7%90%86"><span class="toc-text">3. Vue 的响应式原理</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#4-Vue-%E5%9C%A8%E7%BB%84%E4%BB%B6%E9%97%B4%E7%9A%84%E9%80%9A%E4%BF%A1"><span class="toc-text">4. Vue 在组件间的通信</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#5-Vue-%E7%9A%84%E7%BB%84%E4%BB%B6%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81-export-default"><span class="toc-text">5. Vue 的组件为什么要 export default</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#6-Vue-%E4%B8%AD%E7%BB%99-data-%E4%B8%AD%E7%9A%84%E5%AF%B9%E8%B1%A1%E5%B1%9E%E6%80%A7%E6%B7%BB%E5%8A%A0%E4%B8%80%E4%B8%AA%E6%96%B0%E7%9A%84%E5%B1%9E%E6%80%A7%E6%97%B6%E4%BC%9A%E5%8F%91%E7%94%9F%E4%BB%80%E4%B9%88%EF%BC%8C%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%EF%BC%9F"><span class="toc-text">6. Vue 中给 data 中的对象属性添加一个新的属性时会发生什么，如何解决？</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#7-delete-%E5%92%8C-Vue-delete-%E5%88%A0%E9%99%A4%E6%95%B0%E7%BB%84%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-text">7. delete 和 Vue.delete 删除数组的区别</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#8-vue-js-%E5%88%A4%E6%96%AD%E8%AE%BE%E5%A4%87%E6%98%AF%E6%89%8B%E6%9C%BA%E7%AB%AF%E8%BF%98%E6%98%AFpc%E7%AB%AF"><span class="toc-text">8. vue.js 判断设备是手机端还是pc端</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#9-uniApp-%E5%A6%82%E4%BD%95%E8%8E%B7%E5%8F%96-globalData-%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F"><span class="toc-text">9. uniApp 如何获取 globalData 全局变量</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-jQuery-%E8%8E%B7%E5%8F%96%E7%9A%84-dom-%E5%AF%B9%E8%B1%A1%E5%92%8C%E5%8E%9F%E7%94%9F%E7%9A%84-dom-%E5%AF%B9%E8%B1%A1%E6%9C%89%E4%BD%95%E5%8C%BA%E5%88%AB%EF%BC%9F"><span class="toc-text">1. jQuery 获取的 dom 对象和原生的 dom 对象有何区别？</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2-jQuery-%E5%A6%82%E4%BD%95%E6%89%A9%E5%B1%95%E8%87%AA%E5%AE%9A%E4%B9%89%E6%96%B9%E6%B3%95"><span class="toc-text">2. jQuery 如何扩展自定义方法</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#3-%E5%87%BD%E6%95%B0%E5%A3%B0%E6%98%8E%E4%B8%8E%E8%A1%A8%E8%BE%BE%E5%BC%8F"><span class="toc-text">3. 函数声明与表达式</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#4-JavaScript-%E8%AF%AD%E8%A8%80%E5%AF%B9%E5%8E%9F%E5%9E%8B%E5%AF%B9%E8%B1%A1%E7%9A%84%E7%90%86%E8%A7%A3"><span class="toc-text">4. JavaScript 语言对原型对象的理解</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-%E5%A6%82%E4%BD%95%E4%BC%98%E5%8C%96-SPA-%E5%BA%94%E7%94%A8%E7%9A%84%E9%A6%96%E5%B1%8F%E5%8A%A0%E8%BD%BD%E9%80%9F%E5%BA%A6%E6%85%A2%E7%9A%84%E9%97%AE%E9%A2%98%EF%BC%9F"><span class="toc-text">1. 如何优化 SPA 应用的首屏加载速度慢的问题？</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2-%E5%89%8D%E7%AB%AF%E5%A6%82%E4%BD%95%E4%BC%98%E5%8C%96%E7%BD%91%E7%AB%99%E6%80%A7%E8%83%BD%EF%BC%9F"><span class="toc-text">2. 前端如何优化网站性能？</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#3-%E7%BD%91%E9%A1%B5%E4%BB%8E%E8%BE%93%E5%85%A5%E7%BD%91%E5%9D%80%E5%88%B0%E6%B8%B2%E6%9F%93%E5%AE%8C%E6%88%90%E7%BB%8F%E5%8E%86%E4%BA%86%E5%93%AA%E4%BA%9B%E8%BF%87%E7%A8%8B%EF%BC%9F"><span class="toc-text">3. 网页从输入网址到渲染完成经历了哪些过程？</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-%E8%B0%88%E8%B0%88-Cookie"><span class="toc-text">1. 谈谈 Cookie</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2-%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98%E5%8E%9F%E7%90%86%E4%BB%A5%E5%8F%8A%E6%9C%AC%E5%9C%B0%E5%AD%98%E5%82%A8"><span class="toc-text">2. 浏览器缓存原理以及本地存储</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#A-http-%E7%BC%93%E5%AD%98"><span class="toc-text">A. http 缓存</span></a></li></ol></li></ol>
    </div>
  </section>


  


</aside>



    </div>
    
  
  <footer class="clearfix">
    <br><br>
    
      
        <div class="aplayer-container">
          

  
    <meting-js
      theme='#1BCDFC'
      autoplay='false'
      volume='0.7'
      loop='all'
      order='list'
      fixed='false'
      list-max-height='320px'
      server='netease'
      type='playlist'
      id='3175833810'
      list-folded='true'>
    </meting-js>
  


        </div>
      
    
      
        <br>
        <div class="social-wrapper">
          
            
              <a href="https://missglobefish.github.io/"
                class="social fas fa-rss flat-btn"
                target="_blank"
                rel="external nofollow noopener noreferrer">
              </a>
            
          
            
              <a href="https://missglobefish.github.io/"
                class="social fas fa-envelope flat-btn"
                target="_blank"
                rel="external nofollow noopener noreferrer">
              </a>
            
          
            
              <a href="https://gitee.com/MissGlobeFish"
                class="social fab fa-github flat-btn"
                target="_blank"
                rel="external nofollow noopener noreferrer">
              </a>
            
          
            
              <a href="https://music.163.com/#/user/home?id=63035382"
                class="social fas fa-headphones-alt flat-btn"
                target="_blank"
                rel="external nofollow noopener noreferrer">
              </a>
            
          
        </div>
      
    
      
        <div><p>Blog content follows the <a target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en">Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) License</a></p>
</div>
      
    
      
        Use
        <a href="https://volantis.js.org/" target="_blank" class="codename">Volantis</a>
        as theme, total visits
          <span id="busuanzi_value_site_pv"><i class="fas fa-circle-notch fa-spin fa-fw" aria-hidden="true"></i></span>
          times
        
      
    
      
        <div class='copyright'>
        <p><a href="/">Copyright © 2017-2020 XXX</a></p>

        </div>
      
    
  </footer>


    <a class="s-top fas fa-arrow-up fa-fw" href='javascript:void(0)'></a>
  </div>
  <div>
    
      
  

  <div id="rightmenu-wrapper">
    <ul class="list-v rightmenu" id="rightmenu-content">
      <li class='option'>
        <a class='vlts-menu opt fix-cursor-default' id='menu-copy-text' onclick='document.execCommand("copy")'><i class='fa fa-copy fa-fw'></i>Copy Text</a>
        <hr id='hr-text'>
        <a class='vlts-menu opt fix-cursor-default' id='menu-copy-href'><i class='fa fa-link fa-fw'></i>Copy Link</a>
        <a class='vlts-menu opt fix-cursor-default' id='menu-open-href'><i class='fa fa-external-link-square-alt fa-fw'></i>Open Link in New Tab</a>
        <hr id='hr-href'>
        <a class='vlts-menu opt fix-cursor-default' id='menu-copy-src'><i class='fa fa-image fa-fw'></i>Copy Image Link</a>
        <hr id='hr-src'>
      </li>
      <li class='navigation'>
        <a class='nav icon-only fix-cursor-default' onclick='history.back()'><i class='fa fa-arrow-left fa-fw'></i></a>
        <a class='nav icon-only fix-cursor-default' onclick='history.forward()'><i class='fa fa-arrow-right fa-fw'></i></a>
        <a class='nav icon-only fix-cursor-default' onclick='window.location.reload()'><i class='fa fa-redo fa-fw'></i></a>
        <a class='nav icon-only fix-cursor-default' href='/'><i class='fa fa-home fa-fw'></i></a>
      </li>
      <hr>
      
        
      
        
          
    <li>
      <a class='vlts-menu fix-cursor-default' href=https://gitee.com/MissGlobeFish/lemonElf
        
        
        
        
          id="https:giteecomMissGlobeFishlemonElf"
        >
        <i class='fas fa-envelope fa-fw'></i> 提出问题
      </a>
    </li>
  
        
      
        
      
        
          
    <li>
      <a class='vlts-menu fix-cursor-default' href=https://missglobefish.github.io/
        
        
        
        
          id="https:missglobefishgithubio"
        >
        <i class='fa fa-fan fa-spin fa-fw'></i> 生活博客
      </a>
    </li>
  
        
      
        
          <hr>
        
      
        
          
    <li>
      <a class='vlts-menu fix-cursor-default' href=https://gitee.com/MissGlobeFish/lemonElf
        
        
        
        
          id="https:giteecomMissGlobeFishlemonElf"
        >
        <i class='fa fa-code-branch fa-fw'></i> 本站源码
      </a>
    </li>
  
        
      
        
      
        
          <hr>
        
      
        
          
    <li>
      <a class='vlts-menu fix-cursor-default' 
        
        
        
          onclick="document.execCommand('print')"
        
        >
        <i class='fa fa-print fa-fw'></i> 打印页面
      </a>
    </li>
  
        
      
        
          <hr>
        
      
        
          <li class='music name'>
            <p class='nav music-title fix-cursor-default'></p>
          </li>
          <li class='music ctrl'>
            <a class='nav icon-only backward fix-cursor-default' onclick='aplayerBackward()'><i class='fa fa-step-backward fa-fw'></i></a>
            <a class='nav icon-only toggle fix-cursor-default' onclick='aplayerToggle()'><i class='fa fa-play fa-fw'></i></a>
            <a class='nav icon-only forward fix-cursor-default' onclick='aplayerForward()'><i class='fa fa-step-forward fa-fw'></i></a>
          </li>
          <li class='music volume'>
            <a class='nav volume'>
              <div class="aplayer-volume-bar-wrap">
                <div class="aplayer-volume-bar fix-cursor-pointer">
                  <div class="aplayer-volume"></div>
                  <i class='left fa fa-volume-off fa-fw'></i>
                  <i class='right fa fa-volume-up fa-fw'></i>
                </div>
              </div>
            </a>
          </li>
        
      
    </ul>
  </div>

  <script>
    window.document.oncontextmenu = function (event) {
      if (event.ctrlKey) return true;
      if (/Android|webOS|BlackBerry/i.test(navigator.userAgent)) return true;
      return popMenu(event);
    };
    document.addEventListener("click", function (event) {
      var mymenu = document.getElementById('rightmenu-wrapper');
      mymenu.style.display = "none";
    });
    function popMenu(event) {
      var mymenu = document.getElementById('rightmenu-wrapper');
      var menuContent = document.getElementById('rightmenu-content');
      var screenWidth = document.documentElement.clientWidth || document.body.clientWidth;
      var screenHeight = document.documentElement.clientHeight || document.body.clientHeight;
      mymenu.style.left = event.clientX + "px"; // 获取鼠标位置
      mymenu.style.top = event.clientY + "px";
      mymenu.style.display = 'block';
      if (event.clientX * 2 > screenWidth) {
        menuContent.classList.add('left');
      } else {
        menuContent.classList.remove('left');
      }
      if (event.clientY * 2 > screenHeight) {
        menuContent.classList.add('top');
      } else {
        menuContent.classList.remove('top');
      }

      let hrText = document.getElementById('hr-text');
      let hrSrc = document.getElementById('hr-src');
      let hrHref = document.getElementById('hr-href');

      // 选中图片
      let copySrc = document.getElementById('menu-copy-src');
      if (copySrc != undefined) {
        if (event.target.currentSrc) {
          copySrc.style.display = 'block';
          copySrc.addEventListener("click", function (e) {
            copyString(event.target.currentSrc);
          },{once: true});
          hrSrc.style.display = 'block';
        } else {
          copySrc.style.display = 'none';
          hrSrc.style.display = 'none';
        }
      }

      // 选中按钮
      // 判断是不是按钮
      let href = '';
      if (event.path) {
        for (i = 0; i < event.path.length; i++) {
          if (event.path[i].href != undefined && event.path[i].href.length > 0) {
            href = event.path[i].href;
          }
        }
      }

      let copyText = document.getElementById('menu-copy-text');
      copyText.style.display = 'none';
      hrText.style.display = 'none';
      if (href.length == 0) {
        // 选中文本
        if (window.getSelection().toString()) {
          copyText.style.display = 'block';
          hrText.style.display = 'block';
        }
      }

      // 在新标签页打开
      let openHref = document.getElementById('menu-open-href');
      if (openHref != undefined) {
        if (href.length > 0) {
          openHref.style.display = 'block';
          openHref.addEventListener("click", function (e) {
            window.open(href);
          },{once: true});
          hrHref.style.display = 'block';
        } else {
          openHref.style.display = 'none';
          hrHref.style.display = 'none';
        }
      }
      // 复制链接
      let copyHref = document.getElementById('menu-copy-href');
      if (copyHref != undefined) {
        if (href.length > 0) {
          copyHref.style.display = 'block';
          copyHref.addEventListener("click", function (e) {
            copyString(href);
          },{once: true});
        } else {
          copyHref.style.display = 'none';
        }
      }

      // 有音乐播放器
      if (true == true) {
        // 如果有aplayer，初始化一下
      	try {
      		checkAPlayer();
          updateTitle();
      	} catch (error) {
      		console.log(error);
      	}
      }

      return false; // 该行代码确保系统自带的右键菜单不会被调出
    }
    function hideMenu() {
      document.getElementById('rightmenu-wrapper').style.display = 'none';
    }
    function copyString(str) {
      const input = document.createElement('input');
      input.setAttribute('readonly', 'readonly');
      document.body.appendChild(input);
      input.setAttribute('value', str);
      input.select();
      document.execCommand('copy');
      document.body.removeChild(input);
    }
    document.execCommand('click');
  </script>


    
    
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5/dist/jquery.min.js"></script>



  <script>
    
    var SEARCH_SERVICE = "hexo" || "hexo";
    var ROOT = "/lemonelf/" || "/";
    if (!ROOT.endsWith('/')) ROOT += '/';
  </script>





  <script async src="https://cdn.jsdelivr.net/gh/volantis-x/cdn-volantis@2/js/instant_page.js" type="module" defer integrity="sha384-OeDn4XE77tdHo8pGtE1apMPmAipjoxUQ++eeJa6EtJCfHlvijigWiJpD7VDPWXV1"></script>



  
  
  
    
<script src="https://cdn.jsdelivr.net/npm/jquery-backstretch@2.1.18/jquery.backstretch.min.js"></script>

    <script type="text/javascript">
      $(function(){
        var imgs=["https://gitee.com/wallpapers/minimalist/raw/master/2020/001.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/002.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/003.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/004.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/005.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/006.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/012.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/016.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/019.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/025.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/033.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/034.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/035.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/038.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/039.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/042.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/042.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/046.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/051.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/052.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/054.jpg", "https://gitee.com/wallpapers/minimalist/raw/master/2020/056.jpg"];
        if ('true' == 'true') {
          function shuffle(arr){
            /*From countercurrent-time*/
            var n = arr.length;
            while(n--) {
              var index = Math.floor(Math.random() * n);
              var temp = arr[index];
              arr[index] = arr[n];
              arr[n] = temp;
            }
          }
          shuffle(imgs);
        }
        if ('.cover') {
          $('.cover').backstretch(
            imgs,
          {
            duration: "20000",
            fade: "1500"
          });
        } else {
          $.backstretch(
            imgs,
          {
            duration: "20000",
            fade: "1500"
          });
        }
      });
    </script>
  



  <script>
    let APlayerController = new Object();
    APlayerController.id = '3175833810';  // 设定全局音乐播放ID
    APlayerController.volume = '0.7';
  </script>
  
    
<script src="https://cdn.jsdelivr.net/npm/aplayer@1.10/dist/APlayer.min.js"></script>

  
    
<script src="https://cdn.jsdelivr.net/npm/meting@2.0/dist/Meting.min.js"></script>

  




  
  
<script src="/lemonelf/js/valine.js"></script>


<script>
  var GUEST_INFO = ['nick', 'mail', 'link'];
  var meta = 'nick,mail,link'.split(',').filter(function (item) {
    return GUEST_INFO.indexOf(item) > -1
  });
  var REQUIRED_FIELDS = ['nick', 'mail', 'link'];
  var requiredFields = 'nick,mail'.split(',').filter(function (item) {
    return REQUIRED_FIELDS.indexOf(item) > -1
  });

  function emoji(path, idx, ext) {
    return path + "/" + path + "-" + idx + "." + ext;
  }

  var emojiMaps = {};
  for (var i = 1; i <= 54; i++) {
    emojiMaps['tieba-' + i] = emoji('tieba', i, 'png');
  }
  for (var i = 1; i <= 101; i++) {
    emojiMaps['qq-' + i] = emoji('qq', i, 'gif');
  }
  for (var i = 1; i <= 116; i++) {
    emojiMaps['aru-' + i] = emoji('aru', i, 'gif');
  }
  for (var i = 1; i <= 125; i++) {
    emojiMaps['twemoji-' + i] = emoji('twemoji', i, 'png');
  }
  for (var i = 1; i <= 4; i++) {
    emojiMaps['weibo-' + i] = emoji('weibo', i, 'png');
  }

  function pjax_valine() {
    var valinePath = $.trim($('#valine-path').text()) === "none" ?
            window.location.pathname : $.trim($('#valine-path').text());

    var valinePlaceholder = $.trim($('#valine-placeholder').text()) === "none" ?
            "快来评论吧~" : $.trim($('#valine-placeholder').text());

    var ALLPATH = '';
    if(ALLPATH != '') valinePath = ALLPATH;

    var valine = new Valine();
    valine.init({
      el: '#valine_container',
      meta: meta,
      placeholder: valinePlaceholder,
      path: valinePath,
      appId: "",
      appKey: "",
      pageSize: '10',
      avatar: 'robohash',
      lang: 'zh-cn',
      visitor: 'true',
      highlight: 'true',
      mathJax: 'false',
      enableQQ: 'true',
      requiredFields: requiredFields,
      emojiCDN: 'https://cdn.jsdelivr.net/gh/volantis-x/cdn-emoji/valine/',
      emojiMaps: emojiMaps
    })
  }

  $(function () {
    pjax_valine();
  });
</script>




<!-- darkmodejs -->


<!-- 复制 -->

  <script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>
<script>
    var clipboard = new ClipboardJS('.btn-copy', {
        target: function (trigger) {
            return trigger.nextElementSibling
        }
    });
    function wait(callback, seconds) {
        var timelag = null;
        timelag = window.setTimeout(callback, seconds)
    }
    function pjax_initCopyCode() {
        var copyHtml = '';
        copyHtml += '<button class="btn-copy" data-clipboard-snippet="">';
        copyHtml += '<i class="fas fa-copy"></i><span>COPY</span>';
        copyHtml += '</button>';
        $(".highlight .code pre").before(copyHtml);
        $(".article pre code").before(copyHtml);
        clipboard.off('success').on('success', function (e) {
            let $btn = $(e.trigger);
            $btn.addClass('copied');
            let $icon = $($btn.find('i'));
            $icon.removeClass('fa-copy');
            $icon.addClass('fa-check-circle');
            let $span = $($btn.find('span'));
            $span[0].innerText = 'COPIED';
            wait(function () {
                $icon.removeClass('fa-check-circle');
                $icon.addClass('fa-copy');
                $span[0].innerText = 'COPY'
            }, 2000)
        });
        clipboard.off('error').on('error', function (e) {
            e.clearSelection();
            let $btn = $(e.trigger);
            $btn.addClass('copy-failed');
            let $icon = $($btn.find('i'));
            $icon.removeClass('fa-copy');
            $icon.addClass('fa-times-circle');
            let $span = $($btn.find('span'));
            $span[0].innerText = 'COPY FAILED';
            wait(function () {
                $icon.removeClass('fa-times-circle');
                $icon.addClass('fa-copy');
                $span[0].innerText = 'COPY'
            }, 2000)
        })
    }
    $(function () {
        pjax_initCopyCode()
    });
</script>


<!-- scrollreveal -->

<!-- ******************************** -->

<!-- fancybox -->
<script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script>
<script>
  function pjax_fancybox() {
    $(".article-entry").find("img").not('.inline').not('a img').each(function () { //渲染 fancybox
      var element = document.createElement("a"); // a 标签
      $(element).attr("class", "fancybox");
      $(element).attr("pjax-fancybox", "");  // 过滤 pjax
      $(element).attr("href", $(this).attr("src"));
      if ($(this).attr("data-original")) {
        $(element).attr("href", $(this).attr("data-original"));
      }
      $(element).attr("data-fancybox", "images");
      var caption = "";   // 描述信息
      if ($(this).attr('alt')) {  // 判断当前页面是否存在描述信息
        $(element).attr('data-caption', $(this).attr('alt'));
        caption = $(this).attr('alt');
      }
      var div = document.createElement("div");
      $(div).addClass("fancybox");
      $(this).wrap(div); // 最外层套 div ，其实主要作用还是 class 样式
      var span = document.createElement("span");
      $(span).addClass("image-caption");
      $(span).text(caption); // 加描述
      $(this).after(span);  // 再套一层描述
      $(this).wrap(element);  // 最后套 a 标签
    })
    $(".article-entry").find("img").fancybox({
      selector: '[data-fancybox="images"]',
      hash: false,
      loop: false,
      closeClick: true,
      helpers: {
        overlay: {closeClick: true}
      },
      buttons: [
        "zoom",
        "close"
      ]
    });
  };
  $(function () {
    pjax_fancybox();
  });
</script>

<!-- ******************************** -->


  
<script src="/lemonelf/js/app.js"></script>




  
    
<script src="/lemonelf/js/search.js"></script>

  



  <script defer src="https://cdn.jsdelivr.net/gh/volantis-x/cdn-busuanzi@2.3/js/busuanzi.pure.mini.js" data-pjax></script>



  
<script src="https://cdn.jsdelivr.net/npm/node-waves@0.7.6/dist/waves.min.js"></script>

  <script type="text/javascript">
    $(function () {
      Waves.attach('.flat-btn', ['waves-button']);
      Waves.attach('.float-btn', ['waves-button', 'waves-float']);
      Waves.attach('.float-btn-light', ['waves-button', 'waves-float', 'waves-light']);
      Waves.attach('.flat-box', ['waves-block']);
      Waves.attach('.float-box', ['waves-block', 'waves-float']);
      Waves.attach('.waves-image');
      Waves.init();
    });
  </script>



  
<script src="https://cdn.jsdelivr.net/gh/volantis-x/cdn-volantis@2/js/comment_typing.js"></script>







    
      


<script src="https://cdn.jsdelivr.net/npm/pjax@0.2.8/pjax.min.js"></script>

<!-- 样式位于：source/css/_third-party/pjaxanimate.styl -->

<div class="pjax-animate">
  
    <script src="https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js"></script>
    <div id="loading-bar-wrapper"><script>NProgress.configure({parent:"#loading-bar-wrapper",trickleSpeed: 100})</script></div>
    <script>
      window.ShowLoading = function() {
        NProgress.start();
      };
      window.HideLoading = function() {
        NProgress.done();
      }
    </script>
  
</div>

<script>
    var pjax;
    document.addEventListener('DOMContentLoaded', function () {
      pjax = new Pjax({
        elements: 'a[href]:not([href^="#"]):not([href="javascript:void(0)"]):not([pjax-fancybox])',
        selectors: [
          "title",
          "#pjax-container",
          "#pjax-header-nav-list"
        ],
        cacheBust: false,   // url 地址追加时间戳，用以避免浏览器缓存
        timeout: 5000
      });
    });

    document.addEventListener('pjax:send', function (e) {
      window.stop(); // 相当于点击了浏览器的停止按钮

      try {
        var currentUrl = window.location.pathname;
        var targetUrl = e.triggerElement.href;
        var banUrl = [""];
        if (banUrl[0] != "") {
          banUrl.forEach(item => {
            if(currentUrl.indexOf(item) != -1 || targetUrl.indexOf(item) != -1) {
              window.location.href = targetUrl;
            }
          });
        }
      } catch (error) {}

      window.subData = null; // 移除标题（用于一二级导航栏切换处）
      $.fancybox.close();    // 关闭弹窗
      $('.nav-main').find('.list-v').not('.menu-phone').css("display","none"); // 移除小尾巴
      $('.menu-phone.list-v').css("display","none"); // 移除小尾巴
      $('.l_header .switcher .s-search').removeClass('active'); // 关闭移动端激活的搜索框
      $('.l_header').removeClass('z_search-open'); // 关闭移动端激活的搜索框
      $('.wrapper').removeClass('sub'); // 跳转页面时关闭二级导航

      $('.s-top').unbind('click');   // 解绑
      $('.menu a').unbind('click');  // 解绑
      $(window).unbind('resize');    // 解绑
      $(window).unbind('scroll');    // 解绑
      $(document).unbind('scroll');  // 解绑
      $(document).unbind('click');   // 解绑
      $('body').unbind('click');     // 解绑
      window.ShowLoading();
    });

    document.addEventListener('pjax:complete', function () {
      // 关于百度统计对 SPA 页面的处理：
      // 方案一：百度统计>管理>单页应用设置中，打开开启按钮即可对SPA进行统计。 https://tongji.baidu.com/web/help/article?id=324
      // 方案二：取消注释下列代码。 https://tongji.baidu.com/web/help/article?id=235
      // 

      // 关于谷歌统计对 SPA 页面的处理：
      // 当应用以动态方式加载内容并更新地址栏中的网址时，也应该更新通过 gtag.js 存储的网页网址。
      // https://developers.google.cn/analytics/devguides/collection/gtagjs/single-page-applications?hl=zh-cn
      

      $('.nav-main').find('.list-v').not('.menu-phone').removeAttr("style",""); // 移除小尾巴的移除
      $('.menu-phone.list-v').removeAttr("style",""); // 移除小尾巴的移除
      $('script[data-pjax], .pjax-reload script').each(function () {
        $(this).parent().append($(this).remove());
      });

      try{
        pjax_fancybox();
        
          
          if ('.cover') {
            $('.cover').backstretch("resize");
          } else {
            $.backstretch("resize");
          }
        
        
        
        
          pjax_initCopyCode();
        
        
          pjax_valine();
        
        
        
        
        
      } catch (e) {
        console.log(e);
      }
      window.HideLoading();
    });

    document.addEventListener('pjax:error', function (e) {
      window.HideLoading();
      window.location.href = e.triggerElement.href;
    });
</script>

    
  </div>
</body>
</html>
